home *** CD-ROM | disk | FTP | other *** search
- TITLE Turbo Pascal XMS support for loading overlays - By Wilbert van Leijen
- ; OVERXMS 1.1
- ; Bug fix by Arnold Bailey [72020,136] BIX abailey 1/03/93
- ;
- ; XMS uses BX to return error codes. Most version will preserve the value
- ; of BX if there is no error.
- ;
- ; DRDOS 6 EMM386.SYS and HIDOS.SYS (equivalent to HIMEM.SYS) change
- ; BX to zero if there is no error. The procedure UnitToXMS uses BX as an
- ; offset counter. With DRDOS 6 it gets reset causing major crash.
- ;
- ; Added PUSH BX and POP BX to preserve value.
-
- PAGE 65, 132
- LOCALS @@
-
- Data SEGMENT Word Public
- ASSUME DS:Data
-
- ; XMS block move record
-
- XmsMoveType STRUC
- BlkSize DD ?
- SrcHandle DW ?
- SrcOffset DD ?
- DestHandle DW ?
- DestOffset DD ?
- XmsMoveType ENDS
-
- ; TP overlay manager record
-
- OvrHeader STRUC
- ReturnAddr DD ? ; Virtual return address
- FileOfs DD ? ; Offset into overlay file
- CodeSize DW ? ; Size of overlay
- FixupSize DW ? ; Size of fixup table
- EntryPts DW ? ; Number of procedures
- CodeListNext DW ? ; Segment of next overlay
- LoadSeg DW ? ; Start segment in memory
- Reprieved DW ? ; Loaded in memory flag
- LoadListNext DW ? ; Segment of next in load list
- XmsOffset DD ? ; Offset into allocated XMS block
- UserData DW 3 DUP(?)
- OvrHeader ENDS
-
- XmsDriver DD ? ; Entry point of XMS driver
- ExitSave DD ? ; Pointer to previous exit proc
- XmsMove XmsMoveType <>
- OvrXmsHandle DW ? ; Returned by XMS driver
-
- Extrn PrefixSeg : Word
- Extrn ExitProc : DWord
- Extrn OvrResult : Word
- Extrn OvrCodeList : Word
- Extrn OvrDosHandle : Word
- Extrn OvrHeapOrg : Word
- Extrn OvrReadBuf : DWord
- Data ENDS
-
- Code SEGMENT Byte Public
- ASSUME CS:Code
- Public OvrInitXMS
-
- ovrIOError EQU -4
- ovrNoXMSDriver EQU -7
- ovrNoXMSMemory EQU -8
-
- OvrXmsExit PROC
-
- ; Release handle and XMS memory
-
- MOV DX, [OvrXmsHandle]
- MOV AH, 10
- CALL [XmsDriver]
-
- ; Restore pointer to previous exit procedure
-
- LES AX, [ExitSave]
- MOV Word Ptr [ExitProc], AX
- MOV Word Ptr [ExitProc+2], ES
- RETF
- OvrXmsExit ENDP
-
- AllocateXms PROC
-
- ; Determine the size of the XMS block to allocate:
- ; Walk the CodeListNext chain
- ; Store the total codesize in DX:AX
-
- XOR AX, AX
- XOR DX, DX
- MOV BX, [OvrCodeList]
- @@1: ADD BX, [PrefixSeg]
- ADD BX, 10h
- MOV ES, BX
-
- ;** Ver 1.2 BugFix
- MOV CX, ES:[OvrHeader.CodeSize]
- TEST CX,1 ; Test for odd number of bytes
- JZ @@2
- INC CX ; Make sure it's even number of bytes
- @@2: ADD AX, CX
- ;** Ver 1.2 Bug Fix
-
- ADC DX, 0
- MOV BX, ES:[OvrHeader.CodeListNext]
- OR BX, BX
- JNZ @@1
-
- ; Obtain number of kilobytes to allocate
-
- MOV BX, 1024
- DIV BX
- XCHG DX, AX
- INC DX
-
- ; Allocate the block
-
- MOV AH, 9
- CALL [XmsDriver]
- OR AX, AX
- JZ @@3
- MOV [OvrXmsHandle], DX
- @@3: RETN
- AllocateXms ENDP
-
- ; Function XmsReadFunc(OvrSeg : Word) : Integer; Far;
-
- XmsReadFunc PROC
-
- ; Swap the code from XMS to the heap
-
- PUSH BP
- MOV BP, SP
- MOV ES, [BP+6]
- MOV AX, ES:[OvrHeader.CodeSize]
- MOV Word Ptr [XmsMove.BlkSize], AX
- XOR AX, AX
- MOV Word Ptr [XmsMove.BlkSize+2], AX
- MOV AX, [OvrXmsHandle]
- MOV [XmsMove.SrcHandle], AX
- MOV AX, Word Ptr ES:[OvrHeader.XmsOffset]
- MOV Word Ptr [XmsMove.SrcOffset], AX
- MOV AX, Word Ptr ES:[OvrHeader.XmsOffset+2]
- MOV Word Ptr [XmsMove.SrcOffset+2], AX
- XOR AX, AX
- MOV [XmsMove.DestHandle], AX
- MOV Word Ptr [XmsMove.DestOffset], AX
- MOV AX, ES:[OvrHeader.LoadSeg]
- MOV Word Ptr [XmsMove.DestOffset+2], AX
- MOV AH, 11
- LEA SI, XmsMove
- CALL [XmsDriver]
- OR AX, AX
- JZ @@1
- DEC AX
- JMP @@2
-
- @@1: MOV AX, ovrIOError
- @@2: POP BP
- RETF 2
- XmsReadFunc ENDP
-
- ; Copy an overlaid unit from the heap to XMS
- ; If successful, carry flag is cleared
- ; In/Out:
- ; BX:DI = offset into XMS memory block
-
- CopyUnitToXms PROC
-
- ; XMS requires that an even number of bytes is moved
-
- MOV DX, ES:[OvrHeader.CodeSize]
- TEST DX, 1
- JZ @@1
- INC DX
- INC ES:[OvrHeader.CodeSize]
-
- ; Get the fields of the XMS block move structure
-
- @@1: MOV Word Ptr [XmsMove.BlkSize], DX
- XOR AX, AX
- MOV Word Ptr [XmsMove.BlkSize+2], AX
- MOV [XmsMove.SrcHandle], AX
- MOV Word Ptr [XmsMove.SrcOffset], AX
- MOV AX, [OvrHeapOrg]
- MOV Word Ptr [XmsMove.SrcOffset+2], AX
- MOV AX, [OvrXmsHandle]
- MOV [XmsMove.DestHandle], AX
- MOV Word Ptr [XmsMove.DestOffset], DI
- MOV Word Ptr [XmsMove.DestOffset+2], BX
- MOV AH, 11
- LEA SI, XmsMove
-
- ; BUG Fix. Need to preserve BX
- PUSH BX
-
- CALL [XmsDriver]
-
- ; BUG Fix. Restore BX
- POP BX
-
- ; Bump code size
-
- ADD DI, DX
- ADC BX, 0
-
- ; Check return code from XMS driver
-
- OR AX, AX
- JZ @@2
- CLC
- RETN
-
- @@2: STC
- RETN
- CopyUnitToXms ENDP
-
- OvrXmsLoad PROC
- PUSH BP
- MOV BP, SP
-
- ; Walk the CodeList chain
- ; First segment is PrefixSeg+10h+OvrCodeList
- ; Push each element of overlaid unit list on the stack
- ; Keep the size of the linked list in CX
-
- MOV AX, [OvrCodeList]
- XOR CX, CX
- @@1: ADD AX, [PrefixSeg]
- ADD AX, 10h
- MOV ES, AX
- PUSH AX
- INC CX
- MOV AX, ES:[OvrHeader.CodeListNext]
- OR AX, AX
- JNZ @@1
-
- ; Loop:
- ; Pop each element of the overlaid unit list from the stack
-
- XOR BX, BX
- XOR DI, DI
- @@2: POP ES
- PUSH CX
- MOV AX, [OvrHeapOrg]
- MOV ES:[OvrHeader.LoadSeg], AX
- MOV Word Ptr ES:[OvrHeader.XmsOffset+2], BX
- MOV Word Ptr ES:[OvrHeader.XmsOffset], DI
-
- ; Load overlay from disk
-
- PUSH BX
- PUSH DI
- PUSH ES
- PUSH ES
- CALL [OvrReadBuf]
- POP ES
- POP DI
- POP BX
-
- ; Flag unit as 'unloaded'; check return code
-
- MOV ES:[OvrHeader.LoadSeg], 0
- NEG AX
- JC @@3
-
- CALL CopyUnitToXms
- JC @@3
-
- POP CX
- LOOP @@2
-
- @@3: MOV SP, BP
- POP BP
- RETN
- OvrXMSLoad ENDP
-
- OvrInitXMS PROC
-
- ; Make sure the file's been opened
-
- XOR AX, AX
- CMP AX, [OvrDOSHandle]
- JNE @@1
- DEC AX ; ovrError
- JMP @@5
-
- ; Check presence of XMS driver
-
- @@1: MOV AX, 4300h
- INT 2Fh
- CMP AL, 80h
- JE @@2
- MOV AX, ovrNoXmsDriver
- JMP @@5
-
- ; Get XMS driver's entry point
-
- @@2: MOV AX, 4310h
- INT 2Fh
- MOV Word Ptr [XmsDriver], BX
- MOV Word Ptr [XmsDriver+2], ES
- CALL AllocateXms
- JNZ @@3
- MOV AX, ovrNoXMSMemory
- JMP @@5
-
- ; Load the overlay into XMS
-
- @@3: CALL OvrXmsLoad
- JNC @@4
-
- ; An error occurred. Release handle and XMS memory
-
- MOV DX, [OvrXmsHandle]
- MOV AH, 10
- CALL [XmsDriver]
- MOV AX, ovrIOError
- JMP @@5
-
- ; Close file
-
- @@4: MOV BX, [OvrDOSHandle]
- MOV AH, 3Eh
- INT 21h
-
- ; OvrReadBuf := XmsReadFunc
-
- MOV Word Ptr [OvrReadBuf], Offset XmsReadFunc
- MOV Word Ptr [OvrReadBuf+2], CS
-
- ; ExitSave := ExitProc
- ; ExitProc := OvrXmsExit
-
- LES AX, [ExitProc]
- MOV Word Ptr [ExitSave], AX
- MOV Word Ptr [ExitSave+2], ES
- MOV Word Ptr [ExitProc], Offset OvrXmsExit
- MOV Word Ptr [ExitProc+2], CS
-
- ; Return result of initialisation
-
- XOR AX, AX
- @@5: MOV [OvrResult], AX
- RETF
- OvrInitXMS ENDP
-
- Code ENDS
- END